﻿Imports System.Reflection

''' <summary>
''' リテラルプロパティアーカイブ
''' </summary>
''' <remarks>
''' </remarks>
Public Class LiteralPropertyArchive
    Inherits PropertyArchive

    Private _archivedValue As Object
    ''' <summary>
    ''' アーカイブされた値
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property ArchivedValue As Object
        Get
            Return _archivedValue
        End Get
        Private Set(value As Object)
            _archivedValue = value
        End Set
    End Property

    ''' <summary>
    ''' ユニーク文字列
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides ReadOnly Property Key As String
        Get
            Return Me.PropertyInfo.LiteralName
        End Get
    End Property

    ''' <summary>
    ''' プロパティ情報
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shadows Property PropertyInfo As LiteralProperty
        Get
            Return DirectCast(MyBase.PropertyInfo, LiteralProperty)
        End Get
        Set(value As LiteralProperty)
            MyBase.PropertyInfo = value
        End Set
    End Property

    ''' <summary>
    ''' アーカイブ登録します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <remarks></remarks>
    Public Overrides Sub Regist(instance As Object)
        Dim val = Me.PropertyInfo.GetLiteralValue(instance)
        Me.ArchivedValue = val
    End Sub

    ''' <summary>
    ''' 更新用のリテラル値を取得します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetLiteralValueForUpdate(instance As Object) As Object
        'システム値属性がある場合、通知して動的に変更することを促します
        If Me.HasSystemValue Then
            Me.SystemValueAttribute.RaiseSaveValueReadingEvent(instance, Me.PropertyInfo, Me.ArchivedValue)
        End If

        'プロパティ値を返します
        Return Me.PropertyInfo.GetLiteralValue(instance)
    End Function

    ''' <summary>
    ''' ダーティかどうかを示します
    ''' </summary>
    ''' <param name="instance"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function IsDirty(instance As Object) As Boolean
        'ダーティチェック無効の場合、常にクリーンとします
        If Me.HasSystemValue Then Return False

        'アーカイブ値と比較して返却します
        Dim actual = Me.PropertyInfo.GetLiteralValue(instance)
        Return Not Comparer.Equals(Me.ArchivedValue, actual)
    End Function

    ''' <summary>
    ''' システム値属性を持っているかどうかを示します
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides ReadOnly Property HasSystemValue As Boolean
        Get
            Return Me.PropertyInfo.HasSystemValue
        End Get
    End Property

    ''' <summary>
    ''' システム値属性
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides ReadOnly Property SystemValueAttribute As SpecialValueAttribute
        Get
            Return Me.PropertyInfo.SystemValueAttribute
        End Get
    End Property
End Class
